/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package crp.util;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import jxl.Workbook;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import crp.logic.clustering.NEOClusterFactory;
import crp.object.SymmMatrix;

/**
 *
 * @author ouhang
 */
public class DataOutput {
	
	public void exportXMLBinary(String[] names, SymmMatrix binaryM){
		String targetfile = "Binary"+Math.random()+".xls";
    	WritableWorkbook workbook;
    	
    	String[] title = new String[names.length+1];
    	title[0] = " ";
    	for(int i = 0 ; i < names.length ; i++)
    		title[i+1] = names[i];
    	try{  
    		OutputStream os=new FileOutputStream(targetfile);   
    		workbook=Workbook.createWorkbook(os);   
    	  
    		WritableSheet sheet = workbook.createSheet("Final Result", 0); 
    	  
    		jxl.write.Label label;  
    		for (int i=0; i<title.length; i++){  
    			label = new jxl.write.Label(i, 0, title[i]); //put the title in row1   
    			sheet.addCell(label);  
    			label = new jxl.write.Label(0,i,title[i]);
    			sheet.addCell(label);
    		}
    		jxl.write.Number number;
    		for(int i = 1 ; i < names.length+1; i++)
    			for(int j = 1 ; j < names.length+1 ; j++){
    				number = new jxl.write.Number(i,j,binaryM.getValue(i-1, j-1));
    				sheet.addCell(number);
    			}
    		workbook.write();   
    		workbook.close(); 
    	}catch(Exception e){   
    		e.printStackTrace();   
    	}  
    	
	}
	
	public void exportXMLClusteringResult(String[] names, SymmMatrix binaryM, int centers[]){
		String targetfile = "cluster"+Math.random()+".xls";
    	WritableWorkbook workbook;
    	
    	String[] title = new String[centers.length];
    	for(int i = 0 ; i < centers.length ; i++)
    		title[i] = names[centers[i]];
    	
    	try{  
    		OutputStream os=new FileOutputStream(targetfile);   
    		workbook=Workbook.createWorkbook(os);   
    	  
    		WritableSheet sheet = workbook.createSheet("Final Result", 0); 
    	  
    		jxl.write.Label label;
    		jxl.write.Label label2;
    		for (int i=0; i<title.length; i++){  
    			label = new jxl.write.Label(0, i, title[i]); //put the title in row1   
    			sheet.addCell(label); 
    			int counter = 1;
    			for(int j = 0 ; j < binaryM.dim ; j++){
    				double value = binaryM.getValue(centers[i], j);
    				if(value != 0.0){
    					label2 = new jxl.write.Label(counter++,i,names[j]);
    					sheet.addCell(label2); 
    				}
    			}
    		}
    		
    		label = new jxl.write.Label(0, title.length+1, "Isolated Object");
			sheet.addCell(label);
    		
    		int loc = title.length+2;
    		Integer[] isolate = getIsolateObj(binaryM, centers);
    		if(isolate == null){
    			label = new jxl.write.Label(0, loc++, "no isolated object");
    			sheet.addCell(label);
    		}else{
    			for(Integer iso : isolate){
    				label = new jxl.write.Label(0, loc++, names[iso]);
    				sheet.addCell(label);
    			}
    		}
    		
    		++loc;
    		
    		label = new jxl.write.Label(0, loc, "Repeated Object");
			sheet.addCell(label);
			
			label = new jxl.write.Label(1, loc++, "Number");
			sheet.addCell(label);
    		
    		int[] repeat = getRepeateObj(binaryM, centers);
    		if(repeat == null){
    			label = new jxl.write.Label(0, loc++, "no repeated object");
    			sheet.addCell(label);
    		}else{
    			jxl.write.Number number;
    			for(int i = 0 ; i < repeat.length; i++){
    				label = new jxl.write.Label(0, loc, names[repeat[i]]);
    				sheet.addCell(label);
    				number = new jxl.write.Number(1,loc++, repeat[++i]);
    				sheet.addCell(number);
    			}
    		}
    		
    		workbook.write();   
    		workbook.close(); 
    	}catch(Exception e){   
    		e.printStackTrace();   
    	} 
    	
	}
	
	public Integer[] getIsolateObj(SymmMatrix binaryMa, int centers[]){
		HashSet<Integer> hs = new HashSet<Integer>();
		for(int i = 0 ; i < binaryMa.dim ; i++) hs.add(i);
		
		for(int i = 0 ; i < centers.length ; i++){
			hs.remove(centers[i]);
			for(int j = 0 ; j < binaryMa.dim ; j++)
				if(binaryMa.getValue(centers[i], j) == 1)
					hs.remove(j);
		}
		if(hs.size() == 0) return null;
		
		return hs.toArray(new Integer[hs.size()]);	
	}
	
	public int[] getRepeateObj(SymmMatrix binaryMa, int centers[]){
		Hashtable<Integer, Integer> ht = new Hashtable<Integer, Integer>();
		for(int i = 0 ; i < centers.length ; i++){
			if(ht.containsKey(centers[i])) ht.put(centers[i], ht.get(centers[i])+1);
			else ht.put(centers[i], 1);
			for(int j = 0 ; j < binaryMa.dim ; j++)
				if(binaryMa.getValue(centers[i], j) == 1)
					if(ht.containsKey(j)) ht.put(j, ht.get(j)+1);
					else ht.put(j, 1);
		}
		
		Entry<Integer,Integer>[] sett = ht.entrySet().toArray(new Entry[ht.size()]);
		for(Entry<Integer, Integer> en : sett)
			if(en.getValue() < 2) ht.remove(en.getKey());
		
		if(ht.size() == 0) return null;
		
		Set<Entry<Integer,Integer>> set = ht.entrySet();
        Entry<Integer,Integer>[] entries = (Entry<Integer,Integer>[]) set.toArray(new Entry[set.size()]);

        Arrays.sort(entries,new Comparator(){
            public int compare(Object arg0, Object arg1) {
             int key1 = Integer.parseInt(((Map.Entry)arg0).getValue().toString());
             int key2 = Integer.parseInt(((Map.Entry)arg1).getValue().toString());
             return ((Comparable)key2).compareTo(key1);
            }  
       });
		
		int[] repeat = new int[ht.size()*2];
		int counter = 0;
		for(Entry<Integer, Integer> en : entries){
			repeat[counter++] = en.getKey();
			repeat[counter++] = en.getValue();
		}
		return repeat;	
	}
}
